---
title: Astro 群岛
description: >-
  Astro 群岛（又称组件群岛）是 Astro 开创的一种新 Web 架构模式。“群岛架构”由 Etsy 前端架构工程师 Katie
  Sylor-Miller 于 2019 年首次提出，并由 Preact 的作者 Jason Miller 进行扩展。
---
import IslandsDiagram from '~/components/IslandsDiagram.astro';

Astro 开创并推广了一种叫做 **群岛** 的前端架构。群岛架构通过帮助你避免单体 JavaScript 模式并自动从页面中剥离所有非必需的 JavaScript，从而实现了更好的前端性能。开发者在使用 Astro 的同时，仍然可以继续使用他们最喜欢的 UI 组件和框架，并且从中得到受益。

## 简史

"Etsy" 的前端架构师 [Katie Sylor-Miller](https://twitter.com/ksylor) 在 2019 年首次创造了 "组件岛屿" 这个术语。随后，Preact 的创造者 Jason Miller 在 2020 年 8 月 11 日扩展了这个概念，并在 [这篇文章](https://jasonformat.com/islands-architecture/) 中进行了记录。

> "群岛" 架构的总体思想看似简单：在服务器上渲染 HTML 页面，并在高度动态的区域周围注入占位符或插槽 [...] 这些区域随后可以在客户端 "激活" 成为小型独立的小部件，重用它们服务器渲染的初始 HTML。
> — Jason Miller, Preact 的创造者

这种架构模式所依赖的技术也被称为 **局部化**或**选择性激活**。

相比之下，大多数基于 JavaScript 的 Web 框架会将整个网站作为一个大型 JavaScript 应用程序（也被称为单页应用程序，或 SPA）进行激活和渲染。SPA 提供了简单性和强大的功能，但由于大量使用客户端 JavaScript 也导致存在一些页面加载的性能问题。

SPA 在 [嵌入 Astro 页面内](/zh-cn/guides/migrate-to-astro/from-create-react-app/) 时也有其一席之地。但是，SPA 缺乏选择性和策略性激活的原生能力，使得它们对于当今大多数 Web 项目来说是一个笨重的选择。

Astro 因为是第一个内置选择性激活的主流 JavaScript Web 框架而变得流行，它使用了由 Sylor-Miller 首次提出的组件岛屿模式。

## 什么是群岛？

**在 Astro 中，“岛屿”指的是页面上的任何交互式 UI 组件。** 你可以将岛屿想象成一个个交互式小组件，漂浮在静态、轻量级、服务器渲染的 HTML 海洋中。

<IslandsDiagram>
    <Fragment slot="headerApp">页头（可交互岛屿）</Fragment>
    <Fragment slot="sidebarApp">侧边栏（静态 HTML）</Fragment>
    <Fragment slot="main">
        静态内容（比如文本、图片...）
    </Fragment>
    <Fragment slot="carouselApp">图像轮播（可交互岛屿）</Fragment>
    <Fragment slot="footer">页脚（静态 HTML）</Fragment>
    <Fragment slot="source">来源：[群岛架构：Jason Miller](https://jasonformat.com/islands-architecture/)</Fragment>
</IslandsDiagram>

岛屿始终独立于页面上的其他岛屿运行，且一个页面上可以存在多个岛屿。尽管岛屿在不同的组件上下文中运行，它们仍然可以共享状态并相互通信。

这种灵活性使得 Astro 能够支持多个 UI 框架，如 [React](https://react.dev/)、[Preact](https://preactjs.com/)、[Svelte](https://svelte.dev/)、[Vue](https://vuejs.org/) 和 [SolidJS](https://www.solidjs.com/)。由于它们是独立的，你甚至可以在每个页面上混合使用多种框架。

:::tip
虽然大多数开发者会坚持使用一个 UI 框架，但 Astro 支持在同一个项目中使用多个框架。这允许你：

- 为每个组件选择最合适的框架。
- 无需在启动新项目时学习新框架。
- 即使使用不同的框架也能与他人协作。
- 逐步将现有网站转换为另一个框架，无需停机。
:::

## 创建一个岛屿

默认情况下，Astro 会自动将每个 UI 组件渲染成仅包含 HTML 和 CSS 的形式，**并自动剥离掉所有客户端 JavaScript。**

```astro title="src/pages/index.astro"
<MyReactComponent />
```

这听起来可能很严格，但正是这种做法使得 Astro 网站默认保持快速，并且避免开发者不小心发送不必要或不想要的 JavaScript，而拖慢他们的网站速度。

只需使用一个 `client:*` 指令，就可以将任何静态 UI 组件转变为交互式岛屿。然后 Astro 会自动构建并打包你的客户端 JavaScript，以优化性能。

```astro title="src/pages/index.astro" ins="client:load"
<!-- 现在这个组件在页面上是可交互的了！
  而网站的其他部分仍然是静态。 -->
<MyReactComponent client:load />
```

在使用群岛时，客户端的 JavaScript 只会加载你所使用 `client:*` 指令明确标记的交互组件。

并且由于交互是在组件层面配置的，所以你可以根据每个组件的使用情况来处理不同的加载优先级。例如，`client:idle` 告诉一个组件在浏览器变为空闲时加载，而 `client:visible` 告诉一个组件只有在进入视口后才加载。

## 群岛的好处有哪些？

Astro 群岛的最明显的好处就是性能：你网站的大部分区域都被转换为了快速、静态的 HTML，JavaScript 只有在需要的时候才会加载到各个组件中。JavaScript 是一个加载得最慢的资源。每一个字节都影响着阅读者的体验！

另一个好处是并行加载。在上面的一些假想例子中，重要性更低的图像轮播不应该阻挡更重要的页头部分的加载。它俩并行加载但独自激活（hydrate），这表明阅读者并不需要等着更沉重的图像轮播加载完毕就可以与页头交互了。

更棒的地方在于：你可以准确地告诉 Astro 如何以及何时渲染每个组件。如果该图像轮播的加载成本真的很高，你可以附加一个特殊的客户端指令，告诉 Astro 仅在轮播在页面上可见时才加载它。如果用户从未看到它，它永远不会被加载。

在 Astro 中，作为开发人员，你可以明确告诉 Astro 你的页面上的哪些组件也需要在客户端浏览器中运行。Astro 只会准确地补充页面上需要交互性的内容，并将你的网站的其余部分保留为静态 HTML。

**群岛正是 Astro 在默认情况下能够如此迅速之秘诀！**
